package com.raise.drive.web.controller;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.validation.BindException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.raise.drive.commons.web.springmvc.controller.BaseController;
import com.raise.drive.commons.Utils;
import com.raise.drive.model.service.SearchService;
import com.raise.drive.model.search.SearchRequest;
import com.raise.drive.model.search.InstructorSearchRequest;
import com.raise.drive.web.form.SearchForm;

import java.util.Map;
import java.util.HashMap;

/**
 * @author Eugene Rozov
 */
public class SearchInstructorController extends SimpleFormController {

    private SearchService searchService;

    private int recordsLimit;

    @Override
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
        SearchForm form = (SearchForm) super.formBackingObject(request);
        HttpSession session = request.getSession(false);
        if (session != null) {
            Object attr = session.getAttribute(getFormSessionAttributeName(request));
            if (attr != null) {
                form = (SearchForm) attr;
                session.removeAttribute(getFormSessionAttributeName(request));
            }
        }
        form.getInstructorSearchRequest().setLimit(recordsLimit);

        return form;
    }

//    @Override
//    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
//        super.initBinder(request, binder);
//        binder.registerCustomEditor(Language.class, new LanguagePropertyBinder(languageService));
//    }

//    @Override
//    protected Map<String, Object> referenceData(HttpServletRequest request) throws Exception {
//        Map<String, Object> result = new HashMap<String, Object>(5);
//        result.put(WebConstants.ALL_LANGUAGES_ATTR, languageService.getAllLanguages());
//        return result;
//    }

    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
        SearchForm form = (SearchForm) command;
        InstructorSearchRequest searchRequest = form.getInstructorSearchRequest();

        int total = searchService.getInstructorsCount(searchRequest);
        int page = searchRequest.getPage();

        if (Utils.hasLength(form.getBack())) {
            page--;
        } else if (Utils.hasLength(form.getForward())) {
            page++;
        }
        page = page < 1 ? 1 : page;
        page = page > total / recordsLimit ? total / recordsLimit : page;

        searchRequest.setPage(page);

        form.setInstructors(searchService.getInstructors(searchRequest));
        request.getSession().setAttribute(getFormSessionAttributeName(request), form);

//        applyPaginationAndSorting(request, searchRequest);
        return new ModelAndView(getSuccessView());
    }

    protected void applyPaginationAndSorting(HttpServletRequest request, SearchRequest searchRequest) {
        String start = request.getParameter("start");
        if (Utils.hasLength(start)) {
            searchRequest.setPage(Integer.parseInt(start) / recordsLimit + 1);
        }

        String sortedField = request.getParameter("sort");
        String order = request.getParameter("dir");
        if (order == null) {
            order = "DESC";
        }

        if (Utils.hasLength(sortedField)) {

            // remove prefix like 'category.', 'user.' from a sorted field
            sortedField = sortedField.substring(sortedField.indexOf('.') + 1);
            searchRequest.setSortedField(sortedField);
            searchRequest.setDesc(order.equals("DESC"));
        }
    }

    public void setSearchService(SearchService searchService) {
        this.searchService = searchService;
    }

    public void setRecordsLimit(int recordsLimit) {
        this.recordsLimit = recordsLimit;
    }
}
